package com.koocloud.electroplatemanage.service.impl;

import cn.hutool.core.lang.Validator;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.koocloud.electroplatemanage.Exception.CompaireException;
import com.koocloud.electroplatemanage.auth.mapper.UserMapper;
import com.koocloud.electroplatemanage.common.pojo.ResponseTemplate;
import com.koocloud.electroplatemanage.constant.Constant;
import com.koocloud.electroplatemanage.mapper.AssignJobMapper;
import com.koocloud.electroplatemanage.pojo.AssignJobVo;
import com.koocloud.electroplatemanage.pojo.CodeNameResult;
import com.koocloud.electroplatemanage.pojo.DrawNoVo;
import com.koocloud.electroplatemanage.pojo.TypeWorkVo;
import com.koocloud.electroplatemanage.service.AssignJobService;
import com.koocloud.electroplatemanage.utils.DoubleUtil;
import com.koocloud.electroplatemanage.utils.ListUtil;
import com.koocloud.electroplatemanage.utils.SecondCheck;
import com.koocloud.electroplatemanage.utils.UUIDUtils;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static com.koocloud.electroplatemanage.constant.IncomePartJudgeSqlFieldConstant.*;
import static com.koocloud.electroplatemanage.constant.IncomePartJudgeSqlFieldConstant.ZERO;

/**
 * @program: electroplatemanage
 * @description: 分配工作服务层实现类
 * @author: zww
 * @create: 2020-09-29 16:38
 */
@Service
@Transactional(rollbackFor=Exception.class)
public class AssignJobServiceImpl implements AssignJobService {
    @Resource
    private AssignJobMapper assignJobMapper;
    @Resource
    private UserMapper userMapper;
    Lock lock=new ReentrantLock();
    /**
     *@Description:通过pk查询一条记录
     *@Param: [pk]
     *@return: com.koocloud.electroplatemanage.common.ResponseTemplate
     *@Author: zww
     *@date: 2020/9/29
     */
    @Override
    public ResponseTemplate selectByPk(String pk) {
        try {
            //新建分配工作实体
            AssignJobVo assignJobVo = null;
            assignJobVo = assignJobMapper.selectByPk(pk);
            //将对应员工编号更改成员工姓名
            if (!StringUtils.isEmpty(assignJobVo.getOperatorOne())){
                //更改第1操作人
                CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo.getOperatorOne());
                if (!StringUtils.isEmpty(codeNameResult)){
                    assignJobVo.setOperatorOne(codeNameResult.getName());
                }
            }
            if (!StringUtils.isEmpty(assignJobVo.getOperatorTwo())){
                //更改第2操作人
                CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo.getOperatorTwo());
                if (!StringUtils.isEmpty(codeNameResult)){
                    assignJobVo.setOperatorTwo(codeNameResult.getName());
                }
            }
            if (!StringUtils.isEmpty(assignJobVo.getOperatorThree())){
                //更改第3操作人
                CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo.getOperatorThree());
                if (!StringUtils.isEmpty(codeNameResult)){
                    assignJobVo.setOperatorThree(codeNameResult.getName());
                }
            }
            if (!StringUtils.isEmpty(assignJobVo.getOperatorFour())){
                //更改第4操作人
                CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo.getOperatorFour());
                if (!StringUtils.isEmpty(codeNameResult)){
                    assignJobVo.setOperatorFour(codeNameResult.getName());
                }
            }
            if (!StringUtils.isEmpty(assignJobVo.getOperatorFive())){
                //更改第5操作人
                CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo.getOperatorFive());
                if (!StringUtils.isEmpty(codeNameResult)){
                    assignJobVo.setOperatorFive(codeNameResult.getName());
                }
            }
            //判断查表操作是否成功
            if (null != assignJobVo) {
                //查表成功返回数据
                return ResponseTemplate.builder().code(0).message("查询成功").count(1l).data(assignJobVo).build();
            }
            else {
                //查表失败返回提示
                return ResponseTemplate.builder().code(1).message("没有此数据").count(0l).build();
            }
        } catch (Exception e) {
            //遇到异常，返回异常原因
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
        }

    }
    /**
     *@Description:查询所有记录 分页
     *@Param: [page, limit]
     *@return: com.koocloud.electroplatemanage.common.ResponseTemplate
     *@Author: zww
     *@date: 2020/9/29
     */
    @Override
    public ResponseTemplate selectAllData(String page, String limit,AssignJobVo assignJobVo) {
        //校验分页参数是否为纯数字 并且page和limit不都等于0
        if(Validator.isNumber(page)&&Validator.isNumber(limit)&&!("0".equals(page)&&"0".equals(limit))) {
            try {
                //开始分页
                PageHelper.startPage(Integer.valueOf(page), Integer.valueOf(limit));
                List<AssignJobVo> AssignJobVoList = new ArrayList<>();
                //判断模糊查询是否为状态查询 启用为 1 禁用为 0
                if (!StringUtils.isEmpty(assignJobVo.getIdOrName())){
                    //启用
                    if (STARTUSING.equals(assignJobVo.getIdOrName())){
                        assignJobVo.setIdOrName(ONE);
                        AssignJobVoList = assignJobMapper.selectByDeleteFlag(assignJobVo);
                        //禁用
                    } else if (FORBIDDEN.equals(assignJobVo.getIdOrName())){
                        assignJobVo.setIdOrName(ZERO);
                        AssignJobVoList = assignJobMapper.selectByDeleteFlag(assignJobVo);
                        //模糊查询
                    }else {
                        AssignJobVoList = assignJobMapper.selectAllData(assignJobVo);
                    }
                }else {
                    //全局查询
                    AssignJobVoList = assignJobMapper.selectAllData(assignJobVo);
                }
                for (AssignJobVo assignJobVo1:AssignJobVoList) {
                    //将对应员工编号更改成员工姓名
                    if (!StringUtils.isEmpty(assignJobVo1.getOperatorOne())){
                        //更改第1操作人
                        CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo1.getOperatorOne());
                        if (!StringUtils.isEmpty(codeNameResult)){
                            assignJobVo1.setOperatorOne(codeNameResult.getName());
                        }
                    }
                    if (!StringUtils.isEmpty(assignJobVo1.getOperatorTwo())){
                        //更改第2操作人
                        CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo1.getOperatorTwo());
                        if (!StringUtils.isEmpty(codeNameResult)){
                            assignJobVo1.setOperatorTwo(codeNameResult.getName());
                        }
                    }
                    if (!StringUtils.isEmpty(assignJobVo1.getOperatorThree())){
                        //更改第3操作人
                        CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo1.getOperatorThree());
                        if (!StringUtils.isEmpty(codeNameResult)){
                            assignJobVo1.setOperatorThree(codeNameResult.getName());
                        }
                    }
                    if (!StringUtils.isEmpty(assignJobVo1.getOperatorFour())){
                        //更改第4操作人
                        CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo1.getOperatorFour());
                        if (!StringUtils.isEmpty(codeNameResult)){
                            assignJobVo1.setOperatorFour(codeNameResult.getName());
                        }
                    }
                    if (!StringUtils.isEmpty(assignJobVo1.getOperatorFive())){
                        //更改第5操作人
                        CodeNameResult codeNameResult = userMapper.selectJobNumUser(assignJobVo1.getOperatorFive());
                        if (!StringUtils.isEmpty(codeNameResult)){
                            assignJobVo1.setOperatorFive(codeNameResult.getName());
                        }
                    }
                }
                //构造分页实体
                PageInfo<AssignJobVo> info=new PageInfo<>(AssignJobVoList);
                if (info.getTotal()>0) {
                    //查询到数据
                    return ResponseTemplate.builder().code(0).message("查询成功").count(info.getTotal()).data(info.getList()).build();
                } else {
                    //没有查询到数据
                    return ResponseTemplate.builder().code(1).message("没有查到对应数据").count(0l).build();
                }
            } catch (Exception e) {
                //遇到异常，返回异常原因
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
            }
        }
        else {
            return ResponseTemplate.builder().code(1).message("分页参数错误").count(0l).build();
        }
    }

    /**
     *@Description://插入一条记录
     *@Param: [drawNoVo]
     *@return: com.koocloud.electroplatemanage.common.ResponseTemplate
     *@Author: zww
     *@date: 2020/9/29
     */
    @Override
    public ResponseTemplate insert(AssignJobVo assignJobVo) {
/*        if (!StringUtils.isEmpty(assignJobVo.getAssignjobCode()) && SecondCheck.codeCheck(assignJobVo.getAssignjobCode())) {*/
        try {
            lock.lock();
            //查询工种是否存在
            AssignJobVo assignJobVoByDrawNo = assignJobMapper.selectByDrawNoCode(assignJobVo.getDrawNoCode());
            if (!StringUtils.isEmpty(assignJobVoByDrawNo)) {
                //存在
                return ResponseTemplate.builder().code(1).message("该图号的工作分配方式已存在！").count(0l).build();
            }else {
                //查询工种表中总数
                int sum = assignJobMapper.selectAmount();
                //获取编号字母的字母下标
                int letterGroup = sum / AMOUNT;
                //获取编号数字
                int numberGroup = sum % AMOUNT;
                String str = null;
                //字母数组
                char[] letters = LETTER.toCharArray();
                //判断表中数据为空时和编号数字在0到999之间
                if ((letterGroup == 0 && numberGroup == 0) || (numberGroup > 0 && numberGroup < AMOUNT)) {
                    str = letters[letterGroup] + String.format("%03d", numberGroup + 1);
                } else {
                    str = letters[letterGroup + 1] + String.format("%03d", 1);
                }
                //判断生成的编码是否存在
                while (true) {
                    AssignJobVo assignJobVoByCode = assignJobMapper.selectByCode(str);
                    //存在跳过，继续生成
                    if (!StringUtils.isEmpty(assignJobVoByCode)) {
                        //字母
                        String startStr = null;
                        //数字
                        String endStr = null;
                        startStr = str.substring(0, 1);
                        endStr = str.substring(1);
                        if (Integer.valueOf(endStr) == AMOUNT) {
                            endStr = String.format("%03d", 1);
                            if (startStr.equals(letters[letterGroup])) {
                                startStr = String.valueOf(letters[letterGroup + 1]);
                            } else {
                                startStr = String.valueOf(letters[letterGroup + 2]);
                            }
                            str = startStr + endStr;
                        } else {
                            endStr = String.format("%03d", Integer.valueOf(endStr) + 1);
                            str = startStr + endStr;
                        }
                    } else {
                        break;
                    }
                }
                assignJobVo.setAssignjobCode(str);
            }
            int rows = assignJobMapper.insert(assignJobVo);

/*            AssignJobVo assignJobVo1 = assignJobMapper.selectByCode(assignJobVo.getAssignjobCode());
            if (!StringUtils.isEmpty(assignJobVo1)) {
                return ResponseTemplate.builder().code(1).message("工作分配编码已存在，请重新录入信息").count(0l).build();
            } else {
                //没有异常并且插入数据条数大于0
                rows = assignJobMapper.insert(assignJobVo);
            }*/
            if (rows > 0) {
                return ResponseTemplate.builder().code(0).message("插入数据成功").count(1l).build();
            } else {//没有异常并且插入数据失败，原则上不出现
                return ResponseTemplate.builder().code(1).message("插入数据失败").count(0l).build();
            }

        } catch(Exception e){
            //出现异常返回异常原因
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
        }
        finally {
            lock.unlock();
        }

/*        }else {
            return ResponseTemplate.builder().code(1).message("工作分配编码必须以大写字母开头，其余为数字，长度为4位。").count(0l).build();
        }*/
    }

    /**
     *@Description:批量插入记录
     *@Param: [listDrawNo]
     *@return: com.koocloud.electroplatemanage.common.ResponseTemplate
     *@Author: zww
     *@date: 2020/9/29
     */
    @Override
    public ResponseTemplate batchInsert(List<AssignJobVo> listAssignJobVo) {
        if(!ListUtil.isEmpty(listAssignJobVo)) {
            try {
                lock.lock();
                //没有异常并且插入数据条数大于0
                int rows = assignJobMapper.batchInsert(listAssignJobVo);
                if (rows > 0) {
                    return ResponseTemplate.builder().code(0).message("批量插入数据成功").count((long)rows).build();
                } else {//没有异常并且插入数据失败，原则上不出现
                    return ResponseTemplate.builder().code(1).message("批量插入数据失败").count(0l).build();
                }
            } catch (Exception e) {
                //出现异常返回异常原因
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
            }
            finally {
                lock.unlock();
            }
        }
        else {
            return ResponseTemplate.builder().code(1).message("传入参数为空").count(0l).build();
        }
    }
    /**
     *@Description:逻辑删除一条记录
     *@Param: [pk]
     *@return: com.koocloud.electroplatemanage.common.ResponseTemplate
     *@Author: zww
     *@date: 2020/9/29
     */
    @Override
    public ResponseTemplate delete(String pk,String deleteFlag) {
        try {
            lock.lock();
            int rows = assignJobMapper.delete(pk,deleteFlag);
            //判断删除操作是否成功
            if (rows > 0) {
                //删除成功返回数据
                return ResponseTemplate.builder().code(0).message("删除成功").count(1l).build();
            }
            else {
                //删除失败返回提示
                return ResponseTemplate.builder().code(1).message("删除失败").count(0l).build();
            }
        } catch (Exception e) {
            //遇到异常，返回异常原因
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
        }
        finally {
            lock.unlock();
        }
    }
    /**
     *@Description:通过pks批量逻辑删除记录
     *@Param: [listPks]
     *@return: com.koocloud.electroplatemanage.common.ResponseTemplate
     *@Author: zww
     *@date: 2020/9/29
     */
    @Override
    public ResponseTemplate batchDeleteByPks(List<String> listPks) {
        if(!listPks.isEmpty()) {
            try {
                lock.lock();
                //存在合法pk值，进行批量删除操作
                int rows = assignJobMapper.batchDeleteByPks(listPks);
                //判断批量删除操作是否成功
                if (rows > 0) {
                    //批量删除成功返回数据
                    return ResponseTemplate.builder().code(0).message("批量删除成功").count((long)rows).build();
                } else {
                    //批量删除失败返回提示
                    return ResponseTemplate.builder().code(1).message("批量删除失败").count(0l).build();
                }
            } catch (Exception e) {
                //遇到异常，返回异常原因
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
            }
            finally {
                lock.unlock();
            }
        }
        else {
            return ResponseTemplate.builder().code(1).message("传入参数为空").count(0l).build();
        }
    }
    /**
     *@Description:修改一条记录
     *@Param: [drawNoVo]
     *@return: com.koocloud.electroplatemanage.common.ResponseTemplate
     *@Author: zww
     *@date: 2020/9/29
     */
    @Override
    public ResponseTemplate update(AssignJobVo assignJobVo) {
        try {
            lock.lock();
            //没有异常并且修改数据条数大于0
            int rows = assignJobMapper.update(assignJobVo);
            if(rows>0) {
                return ResponseTemplate.builder().code(0).message("修改数据成功").count(1l).build();
            }
            else {//没有异常并且修改数据失败，原则上不出现
                return ResponseTemplate.builder().code(1).message("修改数据失败").count(0l).build();
            }
        } catch (Exception e) {
            //出现异常返回异常原因
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
        }
        finally {
            lock.unlock();
        }
    }

    /**
     * 校验填写的分配工作表主键
     * @param assignJobVo
     * @return
     */
    @Override
    public ResponseTemplate check(AssignJobVo assignJobVo) {
        try {
            log("传入填写的分配工作表主键："+assignJobVo.getAssignjobCode());

            if (!StringUtils.isEmpty(assignJobVo.getAssignjobCode())){ //判断传入的主键是否为空
                //校验主键的长度
                if (!(assignJobVo.getAssignjobCode().length()==Integer.parseInt(Constant.controlPrikeyLength))){

                    return ResponseTemplate.builder().code(1).message("填写的分配工作表主键必须长度为"+Constant.controlPrikeyLength+"位").count(0l).build();
                }else { //校验长度通过
                    //校验规则
                    if (!SecondCheck.codeCheck(assignJobVo.getAssignjobCode())){
                        //根据主键id查询一条数据
                        AssignJobVo assignJobVo1 = assignJobMapper.selectByPk(assignJobVo.getAssignjobCode());
                        if (!StringUtils.isEmpty(assignJobVo1)){
                            return ResponseTemplate.builder().code(1).message("填写的分配工作表主键已存在,请重新输入").count(1l).build();
                        }else {
                            return ResponseTemplate.builder().code(0).message("此分配工作表主键可用").count(1l).build();
                        }
                    }else {
                        return ResponseTemplate.builder().code(1).message("工作分配编码必须以大写字母开头，其余为数字，长度为4位。").count(0l).build();
                    }


                }
            }else {
                return ResponseTemplate.builder().code(1).message("传入的分配工作表主键为空").count(1l).build();
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseTemplate.builder().code(1).message(e.toString()).count(0l).build();
        }

    }
    /**
     *@Description: 查询用户和工号
     *@Param: []
     *@return: com.koocloud.electroplatemanage.common.pojo.ResponseTemplate
     *@Author: xxc
     *@date: 2020/10/21
     */
    @Override
    public ResponseTemplate selectUserJobNum() {
        try {
            List<CodeNameResult> list = userMapper.selectUserJobNum();
            //判断查表操作是否成功
            if (list.size()>0) {
                //查表成功返回数据
                return ResponseTemplate.builder().code(0).message("查询成功").count(1l).data(list).build();
            }
            else {
                //查表失败返回提示
                return ResponseTemplate.builder().code(1).message("没有此数据").count(0l).build();
            }
        } catch (Exception e) {
            //遇到异常，返回异常原因
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
        }

    }

    /**
     * 分配工作表的操作人校验
     * @param assignJobVo
     * @return
     */
    @Override
    public ResponseTemplate opeVerificat(AssignJobVo assignJobVo) {
        log("输入的第一操作人："+assignJobVo.getOperatorOne());
        log("输入的第一操作人比例："+assignJobVo.getWorkAllocateProportionOne());
        log("输入的第二操作人："+assignJobVo.getOperatorTwo());
        log("输入的第二操作人比例："+assignJobVo.getWorkAllocateProportionTwo());
        log("输入的第三操作人："+assignJobVo.getOperatorThree());
        log("输入的第三操作人比例："+assignJobVo.getWorkAllocateProportionThree());
        log("输入的第四操作人："+assignJobVo.getOperatorFour());
        log("输入的第四操作人比例："+assignJobVo.getWorkAllocateProportionFour());
        log("输入的第五操作人："+assignJobVo.getOperatorFive());
        log("输入的第五操作人比例："+assignJobVo.getWorkAllocateProportionFive());
        if (StringUtils.isEmpty(assignJobVo.getOperatorOne()) || StringUtils.isEmpty(assignJobVo.getWorkAllocateProportionOne())){
            return ResponseTemplate.builder().code(1).message("输入的第一操作人和第一操作人比例不能为空").count(0l).build();
        }else {//不为空的前提下进行判断后面的操作人以及比例
            //分配工作的操作人校验  工作比例  操作人5个人必须得是不同的人 工作比例 第二个人不能比第一个高  加一起一共必须为100% yxx
            // 分别获取五个人的操作人以及对应的比例
            String operatorOne = assignJobVo.getOperatorOne();
            String workAllocateProportionOne = assignJobVo.getWorkAllocateProportionOne();
            String operatorTwo = assignJobVo.getOperatorTwo();
            String workAllocateProportionTwo = assignJobVo.getWorkAllocateProportionTwo();
            String operatorThree = assignJobVo.getOperatorThree();
            String workAllocateProportionThree = assignJobVo.getWorkAllocateProportionThree();
            String operatorFour = assignJobVo.getOperatorFour();
            String workAllocateProportionFour = assignJobVo.getWorkAllocateProportionFour();
            String operatorFive = assignJobVo.getOperatorFive();
            String workAllocateProportionFive = assignJobVo.getWorkAllocateProportionFive();
            //判断输入的参数顺序是否有问题
            Boolean orderFlag = DoubleUtil.FiveOperateOrderCompare(operatorOne, workAllocateProportionOne, operatorTwo, workAllocateProportionTwo, operatorThree, workAllocateProportionThree, operatorFour, workAllocateProportionFour, operatorFive, workAllocateProportionFive);
            if (orderFlag==false){
                return ResponseTemplate.builder().code(1).message("存在上一操作人或操作比例不按顺序输入的情况，请重新核实").count(0l).build();
            }

            //先进行判断分配比例  分配比例传入的是小数  例如0.2
            Boolean flag = false;
            try {
                // 五个数据进行相加 判断是否为1.0 true是  false 否
                flag = DoubleUtil.FiveNumSum(workAllocateProportionOne, workAllocateProportionTwo, workAllocateProportionThree, workAllocateProportionFour, workAllocateProportionFive);
            } catch (CompaireException e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚事务
                return ResponseTemplate.builder().code(1).message(e.getMessage()).count(0l).build();
            }
            if (flag==false){
                return ResponseTemplate.builder().code(1).message("输入的操作比例相加不为1").count(0l).build();
            }
            //分配比例此时是ok的,判断操作人是否有相同的
            Boolean operatorflag = DoubleUtil.FiveOperateCompare(operatorOne, operatorTwo, operatorThree, operatorFour, operatorFive);
            if (operatorflag==false){
                return ResponseTemplate.builder().code(1).message("输入的操作人有相同的请重新分配").count(0l).build();
            }

        }
         return ResponseTemplate.builder().code(0).message("输入比例正确，可以添加").count(0l).build();
    }


    public void  log(String str){
        System.out.println("====================>"+str+"=================>");
    }
}